/*
 * HamamatsuS12573100C.cc
 *
 * @date Feb 10, 2016
 * @author Tim Niggemann, III Phys. Inst. A, RWTH Aachen University
 * @copyright GNU General Public License v3.0
 */

#include "model/impl/HamamatsuS12573100X.hh"

#include <boost/format.hpp>

#include "MaterialFactory.hh"
#include "VectorUtil.hh"
#include "InterpolationUtil.hh"
#include "model/impl/G4SipmRandomGainMapModel.hh"

HamamatsuS12573100X::HamamatsuS12573100X() : G4SipmModel(new G4SipmRandomGainMapModel, new VoltageTraceModel)
{
	setTemperature(25 * CLHEP::kelvin + CLHEP::STP_Temperature);
	setBiasVoltage(getBreakdownVoltage() + 1.4 * CLHEP::volt);
	getGainMapModel()->refresh(this);
	// PDE from the Hamamatsu 13360-6050pe (same resin, metal sheet quenching resistor) scaled to peak at 35 %.
	static const double x[] = {276.63634385444652, 278.59579525864393, 278.81692931702054, 279.0380633753972,
							   279.25919743377381, 279.48724193147467, 279.71528642917559, 279.95024136620077, 280.18174108356379,
							   280.42015124025107, 280.66201661660051, 280.90388199294995, 281.14920258896154, 281.4014336242974,
							   281.65366465963325, 281.9093509146312, 282.16503716962916, 282.42763386395143, 282.6936857779358,
							   282.96664813124443, 283.23961048455311, 283.5160280575239, 283.79935606981894, 284.08268408211399,
							   284.37637775339545, 284.67007142467691, 284.97067553528262, 285.2781900852126, 285.58915985480473,
							   285.90704006372118, 286.23183071196183, 286.5635317995268, 286.90214332641597, 287.24766529262945,
							   287.60009769816725, 287.96289576269135, 288.33605948620192, 288.71958886869891, 289.11693912984435,
							   289.52465504997633, 289.94964706841887, 290.38845996550998, 290.84800418057392, 291.32482449394854,
							   291.83274178428235, 292.36830083191325, 292.93841207616549, 293.5568963956876, 294.20993291183106,
							   294.89406640493377, 295.60929687499566, 296.35562432201681, 297.13650396565924, 297.95539102558519,
							   298.81228550179463, 299.71409783361185, 300.66082802103676, 301.65593128373155, 302.70631806102057,
							   303.81544357256581, 304.98676303802955, 306.23064211639803, 307.55399124699568, 308.9671760888088,
							   310.48056230082386, 312.11142598135149, 313.87704322870241, 315.80851101983575, 317.81599364353605,
							   319.7854688509529, 321.72730230107265, 323.64840443321964, 325.55568568671799, 327.4595117205543,
							   329.36333775439056, 331.27407422755107, 333.20899723834657, 335.19229332441193, 337.29306687898992,
							   339.7497280587678, 342.72121696820369, 346.07969047979873, 349.53145492227139, 352.98321936474406,
							   356.39697639093322, 359.57923369975936, 362.03243965987508, 363.83260910384729, 365.64314420680597,
							   367.43985843111602, 369.2123861177912, 370.95727204716928, 372.67451621925028, 374.35375297504777,
							   375.99152709489965, 377.58092813948173, 379.11850088913172, 380.59042446520112, 381.98633320870357,
							   383.28204058200413, 384.45681526712997, 385.51756770340535, 386.59214101832924, 387.70126652987449,
							   388.87604121500038, 390.16483814897663, 391.63676172504609, 393.3643715561135, 395.37185417981379,
							   397.60392608155286, 399.94656501248028, 402.19245779286791, 404.38306705866137, 406.56331066546841,
							   408.76774080991038, 411.02054402962233, 413.33208598359045, 415.72655320944989, 418.21776658584906,
							   420.8160917717745, 423.53534964587448, 426.38936108679786, 429.38158131420664, 432.5050998887765,
							   435.68044675827832, 438.88689060473951, 442.13134186748402, 445.42071098583631, 448.74808752047215,
							   452.12038191071576, 455.52377327791851, 458.9582616220805, 462.41002606455316, 465.86179050702583,
							   469.28936841186351, 472.66166280210712, 475.97521845809439, 479.22312494050107, 482.4019270296651,
							   485.5185351649107, 488.56949412657576, 491.55134869499807, 494.46409887017774, 497.30428943245249,
							   500.06500994249819, 502.73589474132842, 505.29621251097035, 507.72177671378893, 510.02640822843284,
							   512.29303232679331, 514.54583554650515, 516.78481788756858, 519.01343456964548, 521.23514081239819,
							   523.44993661582657, 525.65436676026854, 527.85534168504842, 530.05286139016607, 532.24001543629743,
							   534.42025904310458, 536.5935922105873, 538.76001493874583, 540.91952722758015, 543.06521863776584,
							   545.20399960862733, 547.32895970084019, 549.43664369474232, 551.52705159033394, 553.58981772862842,
							   555.62148688996376, 557.5978725367047, 559.57425818344586, 561.58865124647059, 563.63414128645422,
							   565.6969074247487, 567.77694966135391, 569.87081277660764, 571.97849677050976, 574.09654642339842,
							   576.22841695493571, 578.36719792579709, 580.51634455564499, 582.6758568444792, 584.84573479229982,
							   587.02252317944476, 589.20967722557612, 591.41065215035587, 593.62199273412216, 595.85060941619918,
							   598.09995741624891, 600.38731283258221, 602.70922044553674, 605.05185937646411, 607.39795352705369,
							   609.74404767764327, 612.08323138890842, 614.40168378220096, 616.68903919853415, 618.92111110027327,
							   621.06334729079686, 623.03973293753791, 624.85372326015863, 626.62279572717171, 628.38841297452268,
							   630.16785110052206, 631.96802054449427, 633.80619740474992, 635.69620255993777, 637.66222254769241,
							   639.7422647842975, 642.0261649809687, 644.57266187196205, 647.01204695342915, 649.39269330064008,
							   651.74224267089176, 654.0710607231706, 656.38951311646304, 658.70451029009337, 661.01605224406148,
							   663.33104941769193, 665.64950181098425, 667.97486464360099, 670.31059313520427, 672.65668728579362,
							   675.01660231503183, 677.39379344258055, 679.79517110776419, 682.2414666285556, 684.73268000495477,
							   687.26190079763751, 689.81876334761728, 692.39981243523187, 695.00504806048161, 697.62755978404186,
							   700.26734760591285, 702.92441152609456, 705.59529632492479, 708.27654678274143, 710.97507333886858,
							   713.68051033432016, 716.39976820842037, 719.12939174150677, 721.86592571391759, 724.61628056497682,
							   727.37700107502258, 730.14463202439242, 732.9226286327488, 735.7109909000917, 738.50626360675881,
							   741.31190197241222, 744.12790599705193, 746.95427568067839, 749.78755580362883, 752.63465680522791,
							   755.48866824615129, 758.35650056572319, 761.2312433246193, 764.12326218182614, 767.02219147835729,
							   769.93839687319894, 772.85460226804071, 775.76735244322037, 778.67319217907584, 781.58248713459318,
							   784.49178209011075, 787.40798748495251, 790.3276480994565, 793.26112959260888, 796.2084319644099,
							   799.16609999519721, 802.14104412429538, 805.13671957136614, 808.13930545776134, 811.14880178348085,
							   814.16866376818655, 817.19889141187866, 820.23602949489521, 823.28353323689817, 826.33449219856323,
							   829.3992720388768, 832.47096231851469, 835.54956303747667, 838.6385294154253, 841.73786145236011,
							   844.84410392861935, 847.96071206386489, 851.08423063843486, 854.22157009165312, 857.36581998419581,
							   860.52043553572491, 863.68541674624032, 866.85730839608004, 870.0430209245684, 873.24255433170526,
							   876.44899817816633, 879.66926290327604, 882.89989328737204, 886.14434455011656, 889.40261669150982,
							   892.67125449188927, 895.95716839057945, 1013.3737545995389};
	static const double y[] = {0, 2.6389385511881005, 2.9367561905440187, 3.23427571414478, 3.5317952377455901,
							   3.8293147613464105, 4.1268342849472202, 4.4243538085480409, 4.7215752163936839, 5.0190947399945038,
							   5.316614263595314, 5.6141337871961339, 5.9113551950417778, 6.2088747186425977, 6.5060961264882993,
							   6.8036156500891201, 7.1008370579347631, 7.3980584657804753, 7.6952798736261965, 7.9927993972269382,
							   8.2900208050726505, 8.5869440971632347, 8.8841655050089372, 9.1813869128546184, 9.4786083207003013,
							   9.7755316127909051, 10.072753020636579, 10.369676312727153, 10.666599604817737, 10.963522896908341,
							   11.260148073243778, 11.557071365334391, 11.853696541669859, 12.150321718005324, 12.44694689434081,
							   12.743572070676276, 13.039899131256606, 13.336226191836964, 13.632553252417342, 13.928582197242562,
							   14.224611142067833, 14.520341971137954, 14.815774684452979, 15.110909282012896, 15.406043879572811,
							   15.70058224562252, 15.994524380161986, 16.287870283191204, 16.580619954710265, 16.87307151047418,
							   17.16462871897275, 17.455887811716213, 17.74625255719436, 18.036021071162271, 18.324895237864869,
							   18.612576941546983, 18.899364297963775, 19.184959191360175, 19.469063505980962, 19.751379126071104,
							   20.031906051630589, 20.310048051149177, 20.585507008871751, 20.85768669328813, 21.125692757132935,
							   21.388332737385738, 21.644712286781221, 21.891850247768247, 22.134516472428647, 22.379567623129905,
							   22.626109352606722, 22.874141660859092, 23.122472084866569, 23.37139874038429, 23.620325395901972,
							   23.868655819909478, 24.115793780896503, 24.359950584332417, 24.596654493890597, 24.805633638223394,
							   24.955585863044256, 25.021767560678903, 25.033095959373124, 25.042039432026446, 25.086756795293123,
							   25.199444550725072, 25.406038769017005, 25.660629623881835, 25.914624247236418, 26.169513217856352,
							   26.425296535741595, 26.682570432402425, 26.941334907838812, 27.201888077805823, 27.464528058058658,
							   27.729254848597225, 27.996366565176725, 28.26616132355219, 28.538937239478766, 28.815290544466695,
							   29.095519354271076, 29.37932555313677, 29.662833636247324, 29.945149256337466, 30.225378066141847,
							   30.502029486884876, 30.771824245260348, 31.02999248918649, 31.272360598091744, 31.500121034996571,
							   31.719236115003181, 31.945804088887552, 32.176545683343491, 32.407585393554527, 32.637134524990046,
							   32.863702498874417, 33.084904389166788, 33.300143964356941, 33.506738182648881, 33.703494581022177,
							   33.887133886170567, 34.055271172053168, 34.204030933853581, 34.331326361285996, 34.449380200309946,
							   34.560577376966371, 34.662831080969447, 34.754650733543635, 34.834247640158296, 34.9001312220378,
							   34.950512784651593, 34.983901749224017, 35.0, 34.993143337632446, 34.95498452097825, 34.890889633629378,
							   34.806224759177844, 34.704269170929877, 34.588004026436579, 34.459218020228619, 34.319103615326426,
							   34.168555158995353, 34.008168882745622, 33.838242902332361, 33.6587772177555, 33.469473713260001,
							   33.269438041580521, 33.057179623941472, 32.835083386383758, 32.610005991274932, 32.383736133145661,
							   32.156571927751052, 31.928811490846225, 31.700454822431187, 31.471501922505912, 31.241952791070425,
							   31.012105543879841, 30.781960180934121, 30.551218586478186, 30.319880760512046, 30.087946703035655,
							   29.855714529804175, 29.622886125062443, 29.389163373055403, 29.154844389538159, 28.919631058755559,
							   28.683523380707619, 28.446223239639234, 28.207134404040218, 27.96566064240027, 27.721205723209245,
							   27.476750804018188, 27.234382695112931, 26.99380328073833, 26.754714445139289, 26.516519956805585,
							   26.279517931492329, 26.043112137689281, 25.807600691151553, 25.572983591879201, 25.33866460836192,
							   25.105239972109977, 24.872411567368282, 24.640179394136801, 24.408841568170661, 24.17809997371473,
							   23.947954610769003, 23.719001710843727, 23.491241273938897, 23.264971415809626, 23.041384599476356,
							   22.820480824939096, 22.601067629177379, 22.382250664925909, 22.163433700674407, 21.9440205049127,
							   21.722818614620294, 21.499231798287024, 21.27176947713734, 21.037748609375161, 20.793293690184136,
							   20.539299066829557, 20.283515748944271, 20.027136199548799, 19.771352881663553, 19.517060142553827,
							   19.264556097974797, 19.015033210946868, 18.769683944490502, 18.531787571911899, 18.308200755578628,
							   18.106376389368464, 17.895608550504971, 17.679176512294372, 17.460657663797999, 17.240350120770948,
							   17.019148230478581, 16.797946340186176, 16.576446334138712, 16.354946328091199, 16.133744437798825,
							   15.913436894771772, 15.693427467499848, 15.474610503248348, 15.25668788626219, 15.040255848051594,
							   14.825910620126752, 14.615142781263248, 14.408846678726423, 14.205531733740729, 14.004899830551016,
							   13.806652853402159, 13.610790802294236, 13.416717445716941, 13.224432783670334, 13.033638700399287,
							   12.84433519590379, 12.656522270183844, 12.469901807484348, 12.284473807805277, 12.100536386901783,
							   11.917493313263597, 11.735642702645871, 11.554984555048597, 11.375518870471755, 11.197245648915374,
							   11.019866774624319, 10.843680363353695, 10.668388299348425, 10.494288698363578, 10.321381560399201,
							   10.149666885455249, 9.9791446735317368, 9.8101130403837864, 9.6419757545011411, 9.4756271631491913,
							   9.3104710348176845, 9.1468054852617477, 8.9849286302364604, 8.8248404697418295, 8.6650504250023275,
							   8.5043660329975008, 8.3430854094824483, 8.1818047859673371, 8.0211203939624998, 7.8607341177127621,
							   7.7018384202386141, 7.544135185784878, 7.3882206458617707, 7.2340948004694301, 7.0826519968730128,
							   6.9335941193175001, 6.7860268205375176, 6.6396519847780064, 6.494767727794085, 6.3513740495856839,
							   6.2088747186425977, 6.0681640822301892, 5.9286459088382131, 5.7906183142218168, 5.6540812983810191,
							   5.5187367455605569, 5.3851808872708604, 5.2531156077566745, 5.1225409070180197, 4.9934567850549438,
							   4.866161357622576, 4.7409527404759153, 4.6172347021048541, 4.495305358264412, 4.3754628247097651,
							   4.2577071014409249, 4.1423363042129582, 4.0290523172708177, 3.9181532563694921, 3.8096391215090608,
							   3.7041061441997596, 3.6015543244415489, 3.5019836622345171, 3.4056922733336252, 3.3129782734941182, 0};
	wvl = std::vector<double>(x, x + sizeof(x) / sizeof(x[0]));
	pde = std::vector<double>(y, y + sizeof(y) / sizeof(y[0]));
	// Apply units.
	wvl = VectorUtil::times(wvl, CLHEP::nanometer);
	pde = VectorUtil::times(pde, CLHEP::perCent);
	// Initialize window material.
	windowMaterial = new G4Material(boost::str(boost::format("%s-windowMaterial") % getName()),
									1.0 * CLHEP::g / CLHEP::cm3, MaterialFactory::getInstance()->getEpoxy());
	double energies[] = {1 * CLHEP::eV, 10 * CLHEP::eV};
	double rindex = 1.41;
	double indices[] = {rindex, rindex};
	// Set material properties table.
	G4MaterialPropertiesTable *mpt = new G4MaterialPropertiesTable();
	mpt->AddProperty("RINDEX", energies, indices, 2);
	windowMaterial->SetMaterialPropertiesTable(mpt);
}

HamamatsuS12573100X::~HamamatsuS12573100X()
{
	//
}

std::string HamamatsuS12573100X::getName() const
{
	return "Hamamatsu S12573-100X";
}

double HamamatsuS12573100X::getBreakdownVoltage() const
{
	return 65 * CLHEP::volt;
}

unsigned int HamamatsuS12573100X::getNumberOfCells() const
{
	return 3600;
}

double HamamatsuS12573100X::getCellPitch() const
{
	return 0.1 * CLHEP::mm;
}

double HamamatsuS12573100X::getThermalNoiseRate() const
{
	return 2.89 * CLHEP::megahertz;
}

double HamamatsuS12573100X::getDeadTime() const
{
	return CLHEP::picosecond;
}

double HamamatsuS12573100X::getRecoveryTime() const
{
	return 22.8 * CLHEP::nanosecond;
}

double HamamatsuS12573100X::getCrossTalkProbability() const
{
	return 35.0 * CLHEP::perCent;
}

double HamamatsuS12573100X::getApProbLong() const
{
	return 0.5 * CLHEP::perCent;
}

double HamamatsuS12573100X::getApProbShort() const
{
	return 0.5 * CLHEP::perCent;
}

double HamamatsuS12573100X::getApTauLong() const
{
	return 85.0 * CLHEP::nanosecond;
}

double HamamatsuS12573100X::getApTauShort() const
{
	return 15.0 * CLHEP::nanosecond;
}

double HamamatsuS12573100X::getFillFactor() const
{
	return 78.5 * CLHEP::perCent;
}

double HamamatsuS12573100X::getGainVariation() const
{
	return 10.0 * CLHEP::perCent;
}

double HamamatsuS12573100X::getPhotonDetectionEfficiency(double wavelength) const
{
	return InterpolationUtil::linear(wvl, pde, wavelength);
}

G4Material *HamamatsuS12573100X::getWindowMaterial() const
{
	return windowMaterial;
}

double HamamatsuS12573100X::getWindowThickness() const
{
	return 0.2 * CLHEP::mm;
}

HamamatsuS12573100X::VoltageTraceModel::VoltageTraceModel() : G4SipmVoltageTraceModel()
{
	//
}

double HamamatsuS12573100X::VoltageTraceModel::getAmplitude() const
{
	return 1.0;
}

double HamamatsuS12573100X::VoltageTraceModel::getTauRise() const
{
	return 1.0 * CLHEP::nanosecond;
}

double HamamatsuS12573100X::VoltageTraceModel::getTauFall() const
{
	return 22.8 * CLHEP::nanosecond;
}

double HamamatsuS12573100X::VoltageTraceModel::getV0() const
{
	return 0.0;
}

double HamamatsuS12573100X::VoltageTraceModel::getWhiteNoiseSigma() const
{
	return 0.01;
}

int HamamatsuS12573100X::VoltageTraceModel::getPrecision() const
{
	return 12;
}

double HamamatsuS12573100X::VoltageTraceModel::getTimeBinWidth() const
{
	return 1.0 * CLHEP::nanosecond;
}
